import 'dart:async';

import 'package:amap_map_fluttify/amap_map_fluttify.dart';
import 'package:flutter/material.dart';
import 'package:detect/utils/storage_util.dart';
import 'package:log4f/log4f.dart';

class LocationNotifier extends ChangeNotifier {
  static final List<String> provinceCity = ['北京', '上海', '天津', '重庆'];
  final Completer<bool> _firstLocation = Completer<bool>();

  Future<bool> get waitLocation => _firstLocation.future;

  List<Location> get locations {
    Map? location = StorageUtil.get<Map>("Locations");
    return location != null
        ? [
            Location(
              address: location['address'],
              accuracy: location['accuracy'],
              adCode: location['adCode'],
              altitude: location['altitude'],
              aoiName: location['aoiName'],
              bearing: location['bearing'],
              city: location['city'],
              cityCode: location['cityCode'],
              country: location['country'],
              district: location['district'],
              latLng: LatLng.fromJson(location['latLng']),
              poiName: location['poiName'],
              province: location['province'],
              speed: location['speed'],
              street: location['street'],
              streetNumber: location['streetNumber'],
            )
          ]
        : [];
  }

  String? get province => locations.isEmpty ? null : locations.last.province;

  String? get city {
    if (locations.isEmpty) {
      return null;
    } else if (provinceCity.indexWhere((e) => locations.last.province?.startsWith(e) ?? false) > 0) {
      return locations.last.province;
    } else {
      return locations.last.city;
    }
  }

  String? get district => locations.isEmpty ? null : locations.last.district;

  String? get address => locations.isEmpty ? null : locations.last.address;

  LatLng? get latLng => locations.isEmpty ? null : locations.last.latLng;

  LocationNotifier() {
    _listenLocation();
  }

  ///持续定位
  void _listenLocation() {
    AmapLocation.instance.fetchLocation(mode: LocationAccuracy.High, needAddress: true).then((location) {
      if ((location.address?.isNotEmpty ?? false) && location.latLng != null && location.latLng!.longitude > 0 && location.latLng!.latitude > 0) {
        push(location);
        Timer(const Duration(minutes: 5), _listenLocation);
      } else {
        // debugPrint("监听定位 => 失败;");
        Log4f.d(msg: "失败；", tag: "监听定位");
        Timer(locations.isNotEmpty ? const Duration(minutes: 5) : const Duration(seconds: 1), _listenLocation);
      }
    }).catchError((error) {
      // debugPrint("监听定位 => 失败;$error");
      Log4f.e(msg: "失败;$error", tag: "监听定位");
      Timer(const Duration(seconds: 1), _listenLocation);
    });
  }

  void push(Location location) async {
    if ((location.address?.isNotEmpty ?? false) && location.latLng != null && location.latLng!.longitude > 0 && location.latLng!.latitude > 0) {
      StorageUtil.set<Map>("Locations", {
        'address': location.address,
        'accuracy': location.accuracy,
        'adCode': location.adCode,
        'altitude': location.altitude,
        'aoiName': location.aoiName,
        'bearing': location.bearing,
        'city': location.city,
        'cityCode': location.cityCode,
        'country': location.country,
        'district': location.district,
        'latLng': location.latLng?.toJson(),
        'poiName': location.poiName,
        'province': location.province,
        'speed': location.speed,
        'street': location.street,
        'streetNumber': location.streetNumber,
      });
      locations.add(location);
      if (!_firstLocation.isCompleted) _firstLocation.complete(true);
      if (locations.length > 10) locations.removeRange(0, 10);
      notifyListeners();
    }
  }
}
